package com.ethink.order.manager;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.ethink.framework.common.constant.CommonRespCode;
import com.ethink.framework.common.exception.BusinessException;
import com.ethink.framework.common.web.context.SPRequestContextHolder;
import com.ethink.order.api.enums.SaleReturnOrderOrderTypeEnum;
import com.ethink.order.api.enums.SaleReturnOrderReturnStatusEnum;
import com.ethink.order.api.enums.TocSaleAfterImportLogOrderTypeEnum;
import com.ethink.order.api.info.SaleOrderInfo;
import com.ethink.order.api.info.TocSaleAfterImportLogDetailInfo;
import com.ethink.order.api.info.TocSaleAfterImportLogInfo;
import com.ethink.order.api.model.SaleDetailOrderModel;
import com.ethink.order.api.request.SaleReturnDetailOrderAddRequest;
import com.ethink.order.api.request.SaleReturnOrderAddRequest;
import com.ethink.order.api.request.TocSaleReturnImportLogResultSettleRequest;
import com.ethink.order.api.response.*;
import com.ethink.order.service.SaleOrderService;
import com.ethink.order.service.SaleReturnOrderService;
import com.ethink.order.service.TocSaleAfterImportLogService;
import com.ethink.order.service.TocSaleReturnImportLogDetailService;
import org.aspectj.weaver.ast.Var;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author default
 * @version 1.0.0
 * @ClassName TocSaleAfterImportManager.java
 * @Description
 * @createTime 2023年01月17日 10:54:00
 */
@Component
public class TocSaleAfterImportManager {

    @Autowired
    private TocSaleAfterImportLogService tocSaleAfterImportLogService;

    @Autowired
    private SaleOrderService saleOrderService;

    @Autowired
    private SaleReturnOrderService saleReturnOrderService;

    @Autowired
    private TocSaleReturnImportLogDetailService tocSaleReturnImportLogDetailService;

    @Transactional(rollbackFor = Exception.class)
    public List<TocSaleAfterImportResponse> settleOrder(Long id) {
        TocSaleAfterImportLogGetResponse response = tocSaleAfterImportLogService.getTocSaleAfterImportLogById(id);
        //判断订单类型  如果是仓库订单全退 退货数量是销售明细
        TocSaleAfterImportLogInfo main = response.getMain();
        List<TocSaleAfterImportResponse> responses = new ArrayList<>();
        List<TocSaleAfterImportLogDetailInfo> item = response.getItem();
        Map<String, List<TocSaleAfterImportLogDetailInfo>> shopOrderNoGroup = item.stream()
                .collect(Collectors.groupingBy(TocSaleAfterImportLogDetailInfo::getShopOrderNo));
        for (Map.Entry<String, List<TocSaleAfterImportLogDetailInfo>> stringListEntry : shopOrderNoGroup.entrySet()) {
            String shopOrderNo = stringListEntry.getKey();
            List<TocSaleAfterImportLogDetailInfo> list = stringListEntry.getValue();
            SaleOrderDetailResponse saleOrderDetailResponse = saleOrderService.getSaleOrderByShopOrderNo(main.getSaleSubChannel(), shopOrderNo);
            //生成销售退单
            SaleAndSaleAfterResponse saleAndSaleAfterResponse = createSaleReturnOrder(saleOrderDetailResponse, list, main.getOrderType());
            TocSaleAfterImportResponse importResponse = responseFill(saleAndSaleAfterResponse.getSaleReturnOrderNo()
                    , saleAndSaleAfterResponse.getSaleOrderDetailResponse(), list, main.getOrderType());
            responses.add(importResponse);
            UpdateStatusReturnImportDetail(shopOrderNo, saleOrderDetailResponse.getMain().getOrderNo(),
                    saleAndSaleAfterResponse.getSaleReturnOrderNo(), main.getSaleSubChannel());
        }
        return responses;

    }

    private void UpdateStatusReturnImportDetail(String shopOrderNo, String orderNo, String returnOrderNo, String saleSubChannel) {
        //更改订单状态
        TocSaleReturnImportLogResultSettleRequest settleRequest = new TocSaleReturnImportLogResultSettleRequest();
        settleRequest.setShopOrderNo(shopOrderNo);
        settleRequest.setOrderNo(orderNo);
        settleRequest.setReturnOrderNo(returnOrderNo);
        settleRequest.setSaleSubChannel(saleSubChannel);
        tocSaleReturnImportLogDetailService.settleOrder(settleRequest);
    }

    private TocSaleAfterImportResponse responseFill(String saleReturnOrderNo
            , SaleOrderDetailResponse saleOrderDetailResponse, List<TocSaleAfterImportLogDetailInfo> list, Integer orderType) {
        TocSaleAfterImportResponse response = new TocSaleAfterImportResponse();
        response.setSaleReturnOrderNo(saleReturnOrderNo);
        response.setSaleOrderDetailResponse(saleOrderDetailResponse);
        response.setList(list);
        response.setOrderType(orderType);
        return response;
    }

    private SaleAndSaleAfterResponse createSaleReturnOrder(SaleOrderDetailResponse saleOrderDetailResponse, List<TocSaleAfterImportLogDetailInfo> list, Integer orderType) {
        SaleAndSaleAfterResponse response = new SaleAndSaleAfterResponse();
        SaleOrderInfo saleOrderInfo = saleOrderDetailResponse.getMain();
        SaleReturnOrderAddRequest addRequest = new SaleReturnOrderAddRequest();
        addRequest.setSaleOrderNo(saleOrderInfo.getOrderNo());
        addRequest.setSubWarehouseCode(list.get(0).getSubWarehouseCode());
        addRequest.setSubWarehouseName(list.get(0).getSubWarehouseName());
        addRequest.setReturnStatus(SaleReturnOrderReturnStatusEnum.S4.getIntValue());
        addRequest.setCreateUserCode(SPRequestContextHolder.getCurrentSystemUserLoginName());
        addRequest.setCreateUserName(SPRequestContextHolder.getCurrentSystemUserRealName());
        addRequest.setOrderType(SaleReturnOrderOrderTypeEnum.T2.getIntValue());
        addRequest.setShopOrderNo(saleOrderInfo.getShopOrderNo());
        List<SaleReturnDetailOrderAddRequest> item = new ArrayList<>();
        List<SaleDetailOrderModel> detailOrderModelList = saleOrderDetailResponse.getItem();
        if (TocSaleAfterImportLogOrderTypeEnum.T1.eq(orderType)) {
            Map<String, Integer> mateSkuAndNum = detailOrderModelList.stream().collect(Collectors
                    .groupingBy(SaleDetailOrderModel::getMateSku, Collectors.summingInt(SaleDetailOrderModel::getOutQty)));
            for (Map.Entry<String, Integer> entry : mateSkuAndNum.entrySet()) {
                SaleReturnDetailOrderAddRequest detailOrderAddRequest = new SaleReturnDetailOrderAddRequest();
                detailOrderAddRequest.setSaleOrderNo(saleOrderInfo.getOrderNo());
                detailOrderAddRequest.setMateSku(entry.getKey());
                detailOrderAddRequest.setReturnQty(entry.getValue());
                item.add(detailOrderAddRequest);
            }
            response.setSaleOrderDetailResponse(saleOrderDetailResponse);
        } else {
            SaleOrderDetailResponse newSaleOrderDetailResponse = new SaleOrderDetailResponse();
            SaleOrderInfo newSaleOrderInfo = BeanUtil.copyProperties(saleOrderDetailResponse.getMain(), SaleOrderInfo.class);
            newSaleOrderDetailResponse.setMain(newSaleOrderInfo);
            List<SaleDetailOrderModel> saleDetailOrderModelList = new ArrayList<>();
            //结算数据按照mateSku分组
            Map<String, List<TocSaleAfterImportLogDetailInfo>> logDetailMateSkuGroup = list.stream()
                    .collect(Collectors.groupingBy(TocSaleAfterImportLogDetailInfo::getMateSku));
            //销售信息按照品
            Map<String, List<SaleDetailOrderModel>> mateGroup = detailOrderModelList.stream()
                    .collect(Collectors.groupingBy(a -> a.getMateSku()));
            for (Map.Entry<String, List<TocSaleAfterImportLogDetailInfo>> listEntry : logDetailMateSkuGroup.entrySet()) {
                String mateSku = listEntry.getKey();
                int sum = 0;
                List<SaleDetailOrderModel> orderModelList = mateGroup.get(mateSku);
                //用于保存无法查询到生产批次的待匹配售后单
                List<TocSaleAfterImportLogDetailInfo> tempLogList = new ArrayList<>();
                for (TocSaleAfterImportLogDetailInfo info : listEntry.getValue()) {
                    //售后单退货数量（可能存在同批次库存不够的情况）
                    Integer returnQty = info.getReturnQty();
                    //销售详情
                    sum += info.getReturnQty();
                    //过滤出来同生产批次的商品
                    List<SaleDetailOrderModel> produceInfoList = orderModelList.stream()
                            .filter(m -> info.getProduceCode().equals(m.getProduceCode())).collect(Collectors.toList());
                    //如果没有命中的生产批次则忽略,优先匹配有生产批次的
                    if (CollUtil.isEmpty(produceInfoList)) {
                        tempLogList.add(info);
                    } else {
                        //生产批次
                        for (SaleDetailOrderModel saleDetailOrderModel : produceInfoList) {
                            if (saleDetailOrderModel.getOutQty() <= 0) {
                                continue;
                            }
                            SaleDetailOrderModel newModel = BeanUtil.copyProperties(saleDetailOrderModel, SaleDetailOrderModel.class);
                            newModel.setInventoryType(info.getInventoryType());
                            //销售明细数量大于售后退数量
                            if (saleDetailOrderModel.getOutQty() > info.getReturnQty()) {
                                newModel.setOutQty(info.getReturnQty());
                                saleDetailOrderModelList.add(newModel);
                                returnQty -= info.getReturnQty();
                                //销售明细中的数量
                                saleDetailOrderModel.setOutQty(saleDetailOrderModel.getOutQty() - info.getReturnQty());
                                break;
                            } else if (saleDetailOrderModel.getOutQty().equals(info.getReturnQty())) {
                                saleDetailOrderModelList.add(newModel);
                                returnQty -= info.getReturnQty();
                                saleDetailOrderModel.setOutQty(0);
                                break;
                            } else if (saleDetailOrderModel.getOutQty() < info.getReturnQty()) {
                                saleDetailOrderModelList.add(newModel);
                                returnQty -= saleDetailOrderModel.getOutQty();
                                saleDetailOrderModel.setOutQty(0);
                            }
                            //修改info结算数量
                            info.setReturnQty(returnQty);
                        }
                        //如果数量还大于0,则代表同生产批次的销售明细数量未能完全匹配，需要从其他生产批次上调取
                        if (returnQty > 0) {
                            info.setReturnQty(returnQty);
                            tempLogList.add(info);
                        }

                    }
                }
                //处理生产批次未查询到的
                if (CollUtil.isNotEmpty(tempLogList)) {
                    for (TocSaleAfterImportLogDetailInfo info : tempLogList) {
                        for (SaleDetailOrderModel saleDetailOrderModel : orderModelList) {
                            if (saleDetailOrderModel.getOutQty() <= 0) {
                                continue;
                            }
                            SaleDetailOrderModel newModel = BeanUtil.copyProperties(saleDetailOrderModel, SaleDetailOrderModel.class);
                            newModel.setProduceCode(info.getProduceCode());
                            if (saleDetailOrderModel.getOutQty() > info.getReturnQty()) {
                                newModel.setOutQty(info.getReturnQty());
                                saleDetailOrderModelList.add(newModel);
                                saleDetailOrderModel.setOutQty(saleDetailOrderModel.getOutQty() - info.getReturnQty());
                                break;
                            } else if (saleDetailOrderModel.getOutQty().equals(info.getReturnQty())) {
                                newModel.setOutQty(info.getReturnQty());
                                saleDetailOrderModelList.add(newModel);
                                saleDetailOrderModel.setOutQty(0);
                                break;
                            } else if (saleDetailOrderModel.getOutQty() < info.getReturnQty()) {
                                info.setReturnQty(info.getReturnQty() - saleDetailOrderModel.getOutQty());
                                newModel.setOutQty(saleDetailOrderModel.getOutQty());
                                saleDetailOrderModelList.add(newModel);
                                saleDetailOrderModel.setOutQty(0);
                            }
                        }
                    }
                }
                SaleReturnDetailOrderAddRequest detailOrderAddRequest = new SaleReturnDetailOrderAddRequest();
                detailOrderAddRequest.setSaleOrderNo(saleOrderInfo.getOrderNo());
                detailOrderAddRequest.setMateSku(mateSku);
                detailOrderAddRequest.setReturnQty(sum);
                item.add(detailOrderAddRequest);
            }
            newSaleOrderDetailResponse.setItem(saleDetailOrderModelList);
            response.setSaleOrderDetailResponse(newSaleOrderDetailResponse);
        }
        addRequest.setItem(item);
        SaleReturnOrderAddResponse add = saleReturnOrderService.add(addRequest);
        response.setSaleReturnOrderNo(add.getOrderNo());
        return response;
    }
}
